//
// Created by Administrator on 2023/3/17.
//

#include "http_connection.h"
#include "net/e_poller.h"
#include "thread"
#include "log/logger_main.h"
void http_connection::closed() {
    if (!is_close)
    {
        holder.closed_by_fd(this->socket_.get_fd());//直接使用holde关闭
    }
}


void http_connection::do_write() {
    this->response_.make_response();

    // while (true) {

    if (this->is_close)
        return;
    int erro = 0;
    int ret = wirte_buff(erro);

    if (ret < 0) {
        if (errno != EAGAIN) {
            LOG_ERROR("error occurred");
            this->holder.closed_by_fd(this->socket_.get_fd());
        } else if (errno == EAGAIN) {
            //重写挂写 提示你的应用程序现在没有数据可读或者没有空间可写
            e_poller::get_instance().update_fd(this->socket_.get_fd(), EPOLLOUT);
        }
        return;
        }

        //那边写完了
    if (ret == 0) {
        //说明写完了挂到读上 并且重置链接
        e_poller::get_instance().update_fd(this->socket_.get_fd(), EPOLLIN);//监听读
        LOG_INFO("写完成====>{}", this->response_.real_path);
        this->response_.reset();
        this->request_.reset();
        return;
    }
    //如果大于0说明需要继续循环
    // }

}

void http_connection::do_read() {
    //获取读入的内容-1 error：为EAGAIN，表示在非阻塞下，此时无数据到达，立即返回。
    while (true) {

        if (this->is_close)
            return;
        auto t = buffer_read.readFd(this->socket_.get_fd());
        LOG_INFO("read bytes : {} ", t);
        LOG_INFO("{}", t);
        //如果==0 表示对端关闭 这边直接关闭就行

        if (t <= 0) {
            auto err = errno;//获取no
            if (err == EAGAIN) {
                break; //没有可读 开始解析
            } else if (err == EINTR) {
                e_poller::get_instance().update_fd(this->socket_.get_fd(), EPOLLIN);

            } else {
                LOG_ERROR("do_read() error fd {} --strerrno  => {}", std::to_string(this->socket_.get_fd()),
                          strerror(err));

                //this->holder.closed_by_fd(this->socket_.get_fd());
                return;
            }

        }

    }
    auto size = buffer_read.readableBytes();
    auto t = buffer_read.retrieveAllAsString();
    auto rt = this->request_.prase(t.data(), t.data() + t.size());
    LOG_INFO("获取结果==>表示 {}", rt);
    if (rt == httpparser::HttpRequestParser::ParsingError) {
        LOG_INFO("请求解析失败==>{}", this->request_.request_result.uri);
        //直接关闭
        this->response_.make_bad_response();
        this->holder.closed_by_fd(this->socket_.get_fd());
        return;
    } else if (rt == httpparser::HttpRequestParser::ParsingIncompleted) {
        //继续解析
        if (!this->is_close && size > 0)
            e_poller::get_instance().update_fd(this->socket_.get_fd(), EPOLLIN);
        return;
    } else if (rt == httpparser::HttpRequestParser::ParsingCompleted) {
        do_write();
        //直接添加写事件
    }


}

void http_connection::start() {
    auto slef = shared_from_this();
    this->holder.add(this->socket_.get_fd(), slef);//加入连接
    //开始监听 读事件
    if (!e_poller::get_instance().add_fd(this->socket_.get_fd(), EPOLLIN)) {
        LOG_ERROR("add_fd 失败 --->{},{}", this->socket_.get_fd(), strerror(errno));
    }
}

http_connection::http_connection(http_connction_holder &holder,  class socket socket) : holder(holder),
                                                                                        socket_(std::move(socket)) {


}

http_connection::~http_connection() {
    LOG_INFO(":~http_connection() ");
//    if (!this->is_close)
//      closed();
}

void http_connection::set_close_flag(bool t) {
    this->is_close = t;
}

void http_connection::do_write_more() {
    // e_poller::get_instance().update_fd(this->socket_.get_fd(),EPOLLOUT);//原始
//    auto ret = buffer_write.writeFd(this->socket_.get_fd());
//    if (ret < 0) {
//        if (errno != EAGAIN) {
//            LOG_ERROR("error occurred");
//            this->holder.closed_by_fd(this->socket_.get_fd());
//        } else {
//            e_poller::get_instance().add_fd(this->socket_.get_fd(), EPOLLOUT);//继续监听写事件
//        }
//        return;
//    }
//    // written += static_cast<size_t>(ret);
//    //assert(written <= buffer_write.readableBytes());
//    //那边取完了
//    if (buffer_write.readableBytes() == 0) {
//        //说明写完了挂到读上 并且重置链接
//        e_poller::get_instance().update_fd(this->socket_.get_fd(), EPOLLIN);//监听读
//        LOG_INFO("写完成====>{}", this->response_.real_path);
//        this->response_.reset();
//        this->request_.reset();
//    } else {
//        do_write_more();
//    }
}

ssize_t http_connection::wirte_buff(int &outError) {
    while (!buffer_write.empty()) {
        int n = buffer_write.size();
        auto ret = write(this->socket_.get_fd(), buffer_write.c_str(), buffer_write.size());
        if (ret < 0) {
            outError = errno;
            return ret;
        }
        buffer_write.erase(buffer_write.begin(), buffer_write.begin() + ret);//加了缓存的删除

    }

    return 0;
}

